home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / dopus412-gpl / program / view.c < prev    next >
C/C++ Source or Header  |  2000-02-28  |  54KB  |  1,851 lines

  1. /*
  2.  
  3. Directory Opus 4
  4. Original GPL release version 4.12
  5. Copyright 1993-2000 Jonathan Potter
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. All users of Directory Opus 4 (including versions distributed
  22. under the GPL) are entitled to upgrade to the latest version of
  23. Directory Opus version 5 at a reduced price. Please see
  24. http://www.gpsoft.com.au for more information.
  25.  
  26. The release of Directory Opus 4 under the GPL in NO WAY affects
  27. the existing commercial status of Directory Opus 5.
  28.  
  29. */
  30.  
  31. #include "dopus.h"
  32. #include "view.h"
  33. #include "searchdata.h"
  34.  
  35. static struct NewWindow
  36.     viewwin={
  37.         0,0,0,0,
  38.         255,255,
  39.         IDCMP_RAWKEY|IDCMP_MOUSEBUTTONS|IDCMP_GADGETUP|
  40.             IDCMP_GADGETDOWN|IDCMP_INACTIVEWINDOW|IDCMP_ACTIVEWINDOW|IDCMP_MOUSEMOVE,
  41.         WFLG_BORDERLESS|WFLG_RMBTRAP,
  42.         NULL,NULL,NULL,NULL,NULL,0,0,0,0,CUSTOMSCREEN},
  43.     ansiread_win={
  44.         0,0,0,0,
  45.         255,255,
  46.         0,
  47.         WFLG_BORDERLESS|WFLG_BACKDROP,
  48.         NULL,NULL,NULL,NULL,NULL,
  49.         0,0,0,0,CUSTOMSCREEN};
  50.  
  51. struct ViewMessage {
  52.     char *filename;
  53.     char *name;
  54.     int function;
  55.     char *initialsearch;
  56.     struct ViewData *viewdata;
  57. };
  58.  
  59. viewfile(filename,name,function,initialsearch,viewdata,wait,noftype)
  60. char *filename,*name;
  61. int function;
  62. char *initialsearch;
  63. struct ViewData *viewdata;
  64. int wait,noftype;
  65. {
  66.     struct ArbiterLaunch launch;
  67.     struct ViewMessage *view_message;
  68.     struct DOpusRemember *memkey=NULL;
  69.     int flags;
  70.  
  71.     if (!noftype) {
  72.         switch (function) {
  73.             case FUNC_HEXREAD:
  74.                 if (checkfiletypefunc(filename,FTFUNC_HEXREAD)) return(1);
  75.                 break;
  76.             case FUNC_ANSIREAD:
  77.                 if (checkfiletypefunc(filename,FTFUNC_ANSIREAD)) return(1);
  78.                 break;
  79.             default:
  80.                 if (checkfiletypefunc(filename,FTFUNC_READ)) return(1);
  81.                 break;
  82.         }
  83.     }
  84.  
  85.     if ((view_message=LAllocRemember(&memkey,sizeof(struct ViewMessage),MEMF_CLEAR)) &&
  86.         copy_string(filename,&view_message->filename,&memkey) &&
  87.         copy_string(name,&view_message->name,&memkey) &&
  88.         copy_string(initialsearch,&view_message->initialsearch,&memkey)) {
  89.  
  90.         launch.launch_code=(void *)view_file_process;
  91.         launch.launch_name="dopus_view";
  92.         launch.launch_memory=memkey;
  93.         launch.data=(APTR)view_message;
  94.  
  95.         view_message->function=function;
  96.         view_message->viewdata=viewdata;
  97.  
  98.         if (wait || viewdata) flags=ARB_WAIT;
  99.         else flags=0;
  100.         return(arbiter_command(ARBITER_LAUNCH,(APTR)&launch,flags));
  101.     }
  102.  
  103.     LFreeRemember(&memkey);
  104.     return(0);
  105. }
  106.  
  107. void __saveds view_file_process()
  108. {
  109.     int a,b,c,in,err,size,old_file_size,old_buffer_size,fsize,retcode=100;
  110.     short
  111.         scroll_speed,
  112.         scroll_pos_1,
  113.         scroll_pos_2,
  114.         scroll_pos_3,
  115.         scroll_pos_4,
  116.         scroll_pos_5,
  117.         scroll_pos_6,
  118.         scroll_pos_7;
  119.     ULONG class;
  120.     USHORT code,qual,gadgetid;
  121.     char buf[60];
  122.     struct ConUnit *view_console_unit=NULL;
  123.     struct ViewData *vdata;
  124.     struct Gadget *gadget;
  125.     struct IntuiMessage *msg;
  126.     struct Process *my_process;
  127.     struct ArbiterMessage *my_startup_message;
  128.     struct ViewMessage *view_msg;
  129.     char *filename,*name;
  130.     int function;
  131.     char *initialsearch;
  132.     struct ViewData *viewdata;
  133.     struct MsgPort *view_port;
  134.     struct IOStdReq *view_req=NULL;
  135.     UBYTE key_matrix[13];
  136.     char portname[20],titlebuf[300];
  137.  
  138.     my_process=(struct Process *)FindTask(NULL);
  139.     WaitPort(&my_process->pr_MsgPort);
  140.     my_startup_message=(struct ArbiterMessage *)GetMsg(&my_process->pr_MsgPort);
  141.  
  142.     view_msg=(struct ViewMessage *)(my_startup_message->data);
  143.     filename=view_msg->filename;
  144.     name=view_msg->name;
  145.     function=view_msg->function;
  146.     initialsearch=view_msg->initialsearch;
  147.     viewdata=view_msg->viewdata;
  148.  
  149.     Forbid();
  150.     for (a=0;;a++) {
  151.         lsprintf(portname,"DOPUS_VIEW%ld",a);
  152.         if (!(FindPort(portname))) break;
  153.     }
  154.     Permit();
  155.  
  156.     if (!(view_port=LCreatePort(portname,0))) goto view_end;
  157.     if (view_req=(struct IOStdReq *)LCreateExtIO(view_port,sizeof(struct IOStdReq))) {
  158.         if (OpenDevice("keyboard.device",0,(struct IORequest *)view_req,0)) {
  159.             LDeleteExtIO((struct IORequest *)view_req);
  160.             view_req=NULL;
  161.             goto view_end;
  162.         }
  163.     }
  164.  
  165.     if (CheckExist(filename,&size)>=0) {
  166.         retcode=-2;
  167.         goto view_end;
  168.     }
  169.     if (size<1) {
  170.         retcode=-3;
  171.         goto view_end;
  172.     }
  173.  
  174.     if (viewdata) vdata=viewdata;
  175.     else {
  176.         if (!(vdata=AllocMem(sizeof(struct ViewData),MEMF_CLEAR))) {
  177.             retcode=-4;
  178.             goto view_end;
  179.         }
  180.     }
  181.  
  182.     strcpy(vdata->view_port_name,portname);
  183.     vdata->view_port=view_port;
  184.     vdata->view_file_size=size;
  185.  
  186.     view_clearsearch(vdata);
  187.  
  188.     vdata->view_search_string[0]=
  189.         vdata->view_scroll_dir=
  190.         vdata->view_scroll=
  191.         vdata->view_last_line=
  192.         vdata->view_last_charpos=0;
  193.     vdata->view_last_char=NULL;
  194.     vdata->view_first_hilite=
  195.         vdata->view_current_hilite=NULL;
  196.     vdata->view_search_flags=search_flags;
  197.  
  198.     if (vdata->view_window) {
  199.         Forbid();    
  200.         vdata->view_window->UserPort->mp_SigTask=(void *)my_process;
  201.         Permit();
  202.     }
  203.     else {
  204.         short scr_pens[ARB_PEN_LASTPEN];
  205.  
  206.         vdata->view_colour_table[PEN_BACKGROUND]=0;
  207.         vdata->view_colour_table[PEN_SHADOW]=config->gadgetbotcol;
  208.         vdata->view_colour_table[PEN_SHINE]=config->gadgettopcol;
  209.         vdata->view_colour_table[PEN_TEXT]=1;
  210.         vdata->view_colour_table[PEN_TEXTBACKGROUND]=0;
  211.         vdata->view_colour_table[VIEWPEN_STATUSTEXT]=config->statusfg;
  212.         vdata->view_colour_table[VIEWPEN_STATUSBACKGROUND]=config->statusbg;
  213.         vdata->view_colour_table[VIEWPEN_LAST_COLOUR]=-1;
  214.  
  215.         if (config->statusbg==0) {
  216.             scr_pens[ARB_PEN_DETAIL]=config->statusbg;
  217.             scr_pens[ARB_PEN_BLOCK]=config->statusfg;
  218.         }
  219.         else {
  220.             scr_pens[ARB_PEN_DETAIL]=config->statusfg;
  221.             scr_pens[ARB_PEN_BLOCK]=config->statusbg;
  222.         }
  223.  
  224.         if (!(vdata->view_screen=
  225.             open_subprocess_screen(globstring[STR_TEXT_VIEWER_TITLE],
  226.                 scr_font[FONT_TEXT],&vdata->view_memory,
  227.                 (system_version2)?NULL:scr_pens)) ||
  228.                 !(vdata->view_font=OpenFont(vdata->view_screen->Font))) {
  229.             retcode=-4;
  230.             goto view_end;
  231.         }
  232.  
  233.         viewwin.TopEdge=vdata->view_screen->BarHeight+2;
  234.         viewwin.Width=vdata->view_screen->Width;
  235.         viewwin.Height=vdata->view_screen->Height-(vdata->view_screen->BarHeight+2);
  236.         viewwin.Screen=vdata->view_screen;
  237.         viewwin.BlockPen=vdata->view_colour_table[PEN_SHINE];
  238.  
  239.         if (!(vdata->view_gadgets=LAllocRemember(&vdata->view_memory,
  240.                 sizeof(struct Gadget)*VIEW_GADGET_COUNT,MEMF_CLEAR)) ||
  241.             !(vdata->view_window=OpenWindow(&viewwin))) {
  242.             CloseScreen(vdata->view_screen);
  243.             LFreeRemember(&vdata->view_memory);
  244.             if (!viewdata) FreeMem(vdata,sizeof(struct ViewData));
  245.             retcode=-4;
  246.             goto view_end;
  247.         }
  248.  
  249.         vdata->view_rastport=vdata->view_window->RPort;
  250.  
  251.         vdata->view_status_bar_ypos=vdata->view_window->Height-(vdata->view_font->tf_YSize+1);
  252.  
  253.         vdata->view_vis_info.vi_fg=vdata->view_colour_table[VIEWPEN_STATUSTEXT];
  254.         vdata->view_vis_info.vi_bg=vdata->view_colour_table[VIEWPEN_STATUSBACKGROUND];
  255.         vdata->view_vis_info.vi_shine=vdata->view_colour_table[PEN_SHINE];
  256.         vdata->view_vis_info.vi_shadow=vdata->view_colour_table[PEN_SHADOW];
  257.  
  258.         vdata->view_vis_info.vi_stringcol[0]=vdata->view_colour_table[PEN_TEXT];
  259.         vdata->view_vis_info.vi_stringcol[1]=vdata->view_colour_table[PEN_TEXTBACKGROUND];
  260.         vdata->view_vis_info.vi_activestringcol[0]=vdata->view_colour_table[PEN_TEXT];
  261.         vdata->view_vis_info.vi_activestringcol[1]=vdata->view_colour_table[PEN_TEXTBACKGROUND];
  262.  
  263.         if (vdata->view_window->UserData=LAllocRemember(&vdata->view_memory,SEARCH_COLOURS,0)) {
  264.             vdata->view_window->UserData[SEARCH_COL_FG]=
  265.                 vdata->view_colour_table[VIEWPEN_STATUSTEXT];
  266.             vdata->view_window->UserData[SEARCH_COL_BG]=
  267.                 vdata->view_colour_table[VIEWPEN_STATUSBACKGROUND];
  268.             vdata->view_window->UserData[SEARCH_COL_SHINE]=
  269.                 vdata->view_colour_table[PEN_SHINE];
  270.             vdata->view_window->UserData[SEARCH_COL_SHADOW]=
  271.                 vdata->view_colour_table[PEN_SHADOW];
  272.             vdata->view_window->UserData[SEARCH_COL_STRINGFG]=
  273.                 vdata->view_colour_table[PEN_TEXT];
  274.             vdata->view_window->UserData[SEARCH_COL_STRINGBG]=
  275.                 vdata->view_colour_table[PEN_TEXTBACKGROUND];
  276.             vdata->view_window->UserData[SEARCH_COL_STRINGSELFG]=
  277.                 vdata->view_colour_table[PEN_TEXT];
  278.             vdata->view_window->UserData[SEARCH_COL_STRINGSELBG]=
  279.                 vdata->view_colour_table[PEN_TEXTBACKGROUND];
  280.         }
  281.  
  282.         vdata->view_vis_info.vi_font=vdata->view_font;
  283.         if (vdata->view_vis_info.vi_flags&VISF_WINDOW)
  284.             vdata->view_vis_info.vi_screen=(struct Screen *)vdata->view_window;
  285.         else vdata->view_vis_info.vi_screen=vdata->view_screen;
  286.  
  287.         if (config->generalscreenflags&SCR_GENERAL_REQDRAG)
  288.             vdata->view_vis_info.vi_flags|=VISF_BORDERS;
  289.  
  290.         vdata->view_vis_info.vi_language=config->language;
  291.  
  292.         if (config->viewbits&VIEWBITS_TEXTBORDERS) {
  293.             vdata->view_lines_per_screen=(vdata->view_status_bar_ypos-6)/vdata->view_font->tf_YSize;
  294.  
  295.             vdata->view_display_left=4;
  296.             vdata->view_display_top=((vdata->view_status_bar_ypos-6)-
  297.                 (vdata->view_lines_per_screen*vdata->view_font->tf_YSize))/2;
  298.             if (vdata->view_display_top<2) vdata->view_display_top=2;
  299.  
  300.             vdata->view_display_right=vdata->view_window->Width-20;
  301.             vdata->view_display_bottom=vdata->view_status_bar_ypos-5;
  302.  
  303.             Do3DBox(vdata->view_rastport,vdata->view_display_left-2,1,
  304.                 (vdata->view_display_right-vdata->view_display_left)+4,
  305.                 vdata->view_display_bottom,
  306.                 vdata->view_colour_table[PEN_SHINE],
  307.                 vdata->view_colour_table[PEN_SHADOW]);
  308.  
  309.             vdata->view_gadgets[VIEW_SCROLLGADGET].LeftEdge=vdata->view_display_right+8;
  310.             vdata->view_gadgets[VIEW_SCROLLGADGET].TopEdge=2;
  311.             vdata->view_gadgets[VIEW_SCROLLGADGET].Height=vdata->view_display_bottom-2;
  312.             vdata->view_gadgets[VIEW_SCROLLGADGET].Width=8;
  313.             vdata->view_gadgets[VIEW_SCROLLGADGET].Flags=GFLG_GADGHNONE;
  314.             vdata->view_gadgets[VIEW_SCROLLGADGET].Activation=
  315.                 GACT_IMMEDIATE|GACT_RELVERIFY|GACT_FOLLOWMOUSE;
  316.             vdata->view_gadgets[VIEW_SCROLLGADGET].GadgetType=GTYP_PROPGADGET;
  317.             vdata->view_gadgets[VIEW_SCROLLGADGET].GadgetRender=
  318.                 (APTR)&vdata->view_prop_image;
  319.             vdata->view_gadgets[VIEW_SCROLLGADGET].SpecialInfo=
  320.                 (APTR)&vdata->view_prop_info;
  321.             vdata->view_gadgets[VIEW_SCROLLGADGET].GadgetID=VIEW_SCROLLGADGET;
  322.  
  323.             vdata->view_prop_info.Flags=AUTOKNOB|FREEVERT|PROPNEWLOOK|PROPBORDERLESS;
  324.             vdata->view_prop_info.VertBody=MAXBODY;
  325.  
  326.             AddGList(vdata->view_window,&vdata->view_gadgets[VIEW_SCROLLGADGET],-1,1,NULL);
  327.             RefreshGList(&vdata->view_gadgets[VIEW_SCROLLGADGET],vdata->view_window,NULL,1);
  328.             Do3DBox(vdata->view_rastport,
  329.                 vdata->view_gadgets[VIEW_SCROLLGADGET].LeftEdge-2,
  330.                 vdata->view_gadgets[VIEW_SCROLLGADGET].TopEdge-1,
  331.                 vdata->view_gadgets[VIEW_SCROLLGADGET].Width+4,
  332.                 vdata->view_gadgets[VIEW_SCROLLGADGET].Height+2,
  333.                 vdata->view_colour_table[PEN_SHINE],
  334.                 vdata->view_colour_table[PEN_SHADOW]);
  335.  
  336.             vdata->view_scroll_bar=1;
  337.         }
  338.         else {
  339.             vdata->view_lines_per_screen=(vdata->view_status_bar_ypos-1)/vdata->view_font->tf_YSize;
  340.  
  341.             vdata->view_display_left=vdata->view_display_top=0;
  342.             vdata->view_display_right=vdata->view_window->Width-1;
  343.             vdata->view_display_bottom=vdata->view_display_top+
  344.                 (vdata->view_lines_per_screen*vdata->view_font->tf_YSize)-1;
  345.         }
  346.  
  347.         vdata->view_display_height=vdata->view_lines_per_screen*vdata->view_font->tf_YSize;
  348.  
  349.         for (a=9;a<11;a++) {
  350.             vdata->view_gadgets[a].TopEdge=vdata->view_status_bar_ypos;
  351.             vdata->view_gadgets[a].Width=vdata->view_font->tf_XSize*((a==9)?6:4);
  352.             vdata->view_gadgets[a].Height=vdata->view_font->tf_YSize;
  353.             vdata->view_gadgets[a].Flags=GFLG_GADGHCOMP;
  354.             vdata->view_gadgets[a].Activation=GACT_RELVERIFY;
  355.             vdata->view_gadgets[a].GadgetType=GTYP_BOOLGADGET;
  356.             vdata->view_gadgets[a].GadgetID=a;
  357.         }
  358.  
  359.         vdata->view_gadgets[VIEW_JUMPTOLINE].NextGadget=&vdata->view_gadgets[VIEW_JUMPTOPERCENT];
  360.         vdata->view_gadgets[VIEW_JUMPTOLINE].LeftEdge=
  361.             vdata->view_window->Width-((vdata->view_font->tf_XSize*49)+14);
  362.         vdata->view_gadgets[VIEW_JUMPTOPERCENT].LeftEdge=
  363.             vdata->view_window->Width-((vdata->view_font->tf_XSize*22)+14);
  364.  
  365.         view_setupscreen(vdata);
  366.         AddGadgetBorders(&vdata->view_memory,
  367.             vdata->view_gadgets,9,
  368.             vdata->view_colour_table[PEN_SHINE],vdata->view_colour_table[PEN_SHADOW]);
  369.         AddGList(vdata->view_window,vdata->view_gadgets,-1,11,NULL);
  370.     }
  371.  
  372.     vdata->view_char_width=((vdata->view_display_right-vdata->view_display_left)+1)/
  373.         vdata->view_font->tf_XSize;
  374.  
  375.     if (function==FUNC_HEXREAD) {
  376.         vdata->view_char_width=(vdata->view_char_width>62)?62:vdata->view_char_width;
  377.         vdata->view_max_line_length=16;
  378.     }
  379.     else vdata->view_max_line_length=vdata->view_char_width+1;
  380.  
  381.     a=vdata->view_window->Height/8;
  382.     scroll_pos_1=a;
  383.     scroll_pos_2=a*2;
  384.     scroll_pos_3=a*3;
  385.     scroll_pos_4=a*4;
  386.     scroll_pos_5=a*5;
  387.     scroll_pos_6=a*6;
  388.     scroll_pos_7=a*7;
  389.  
  390.     vdata->view_display_as_hex=(function==FUNC_HEXREAD);
  391.  
  392.     view_busy(vdata);
  393.     ActivateWindow(vdata->view_window);
  394.  
  395.     view_status_text(vdata,globstring[STR_READING_FILE]);
  396. tryload:
  397.     if (vdata->view_file_size>16) {
  398.         if (!PPBase ||
  399.             (err=ppLoadData(filename,DECR_POINTER,MEMF_CLEAR,
  400.                 (UBYTE **)&vdata->view_text_buffer,&size,NULL))==PP_UNKNOWNPP)
  401.             goto readnormal;
  402.  
  403.         old_file_size=vdata->view_file_size;
  404.         old_buffer_size=vdata->view_buffer_size;
  405.  
  406.         vdata->view_file_size=vdata->view_buffer_size=size;
  407.  
  408.         if ((size%16)==0) size+=16;
  409.         else size=((vdata->view_file_size/16)+1)*16;
  410.  
  411.         vdata->view_last_char=vdata->view_text_buffer+size-16;
  412.         vdata->view_last_charpos=vdata->view_file_size-
  413.             (vdata->view_last_char-vdata->view_text_buffer);
  414.  
  415.         if (err) {
  416.             vdata->view_text_buffer=NULL;
  417.             vdata->view_file_size=0;
  418.  
  419.             if (err==PP_NOMEMORY) {
  420.                 view_status_text(vdata,globstring[STR_NO_MEMORY_TO_DECRUNCH]);
  421.                 vdata->view_file_size=old_file_size;
  422.                 vdata->view_buffer_size=old_buffer_size;
  423.                 goto readnormal;
  424.             }
  425.             else if (err==PP_PASSERR) {
  426.                 view_status_text(vdata,globstring[STR_BAD_PASSWORD]);
  427.                 view_simplerequest(vdata,globstring[STR_BAD_PASSWORD],globstring[STR_CONTINUE],NULL);
  428.                 goto cleanup;
  429.             }
  430.             else {
  431. readnormal:
  432.                 if (!(in=Open(filename,MODE_OLDFILE))) goto cleanup;
  433.                 if ((vdata->view_file_size%16)==0)
  434.                     vdata->view_buffer_size=vdata->view_file_size+16;
  435.                 else vdata->view_buffer_size=((vdata->view_file_size/16)+1)*16;
  436.  
  437.                 for (a=0;a<2;a++) {
  438.                     if (vdata->view_text_buffer=AllocMem(vdata->view_buffer_size,MEMF_CLEAR))
  439.                         break;
  440.                     if ((vdata->view_buffer_size=AvailMem(MEMF_PUBLIC|MEMF_LARGEST))<16)
  441.                         break;
  442.                     if (vdata->view_buffer_size<=vdata->view_file_size)
  443.                         vdata->view_file_size=vdata->view_buffer_size;
  444.                 }
  445.                 if (!vdata->view_text_buffer) {
  446.                     Close(in);
  447.                     goto cleanup;
  448.                 }
  449.  
  450.                 fsize=Read(in,vdata->view_text_buffer,vdata->view_file_size);
  451.  
  452.                 if (vdata->view_buffer_size!=vdata->view_file_size &&
  453.                     fsize>-1 && fsize!=vdata->view_file_size) vdata->view_file_size=fsize;
  454.  
  455.                 Close(in);
  456.                 if (fsize==-1) goto cleanup;
  457.                 vdata->view_last_char=vdata->view_text_buffer+vdata->view_buffer_size-16;
  458.                 vdata->view_last_charpos=vdata->view_file_size-
  459.                     (vdata->view_last_char-vdata->view_text_buffer);
  460.             }
  461.         }
  462.     }
  463.     else {
  464.         vdata->view_buffer_size=16;
  465.         if (!(in=Open(filename,MODE_OLDFILE))) goto cleanup;
  466.         if (!(vdata->view_text_buffer=AllocMem(16,MEMF_CLEAR))) {
  467.             Close(in);
  468.             goto cleanup;
  469.         }
  470.         vdata->view_file_size=Read(in,vdata->view_text_buffer,16);
  471.         Close(in);
  472.         vdata->view_last_char=vdata->view_text_buffer;
  473.         vdata->view_last_charpos=vdata->view_file_size;
  474.     }
  475.  
  476.     vdata->view_text_offset=
  477.         vdata->view_old_offset=
  478.         vdata->view_line_count=
  479.         vdata->view_top_buffer_pos=
  480.         vdata->view_bottom_buffer_pos=0;
  481.  
  482.     view_status_text(vdata,globstring[STR_COUNTING_LINES]);
  483.  
  484.     if (function==FUNC_SMARTREAD) {
  485.         if ((vdata->view_line_count=smartcountlines(vdata))==-1) {
  486.             vdata->view_display_as_hex=1;
  487.             vdata->view_max_line_length=16;
  488.             vdata->view_char_width=62;
  489.         }
  490.         else if (vdata->view_line_count==-2) function=FUNC_ANSIREAD;
  491.         else removetabs(vdata);
  492.     }
  493.  
  494.     if (function==FUNC_ANSIREAD) {
  495.         vdata->view_tab_size=config->tabsize;
  496.         vdata->view_line_count=ansicountlines(vdata);
  497.     }
  498.     else {
  499.         if (vdata->view_display_as_hex) {
  500.             vdata->view_file_size=vdata->view_buffer_size;
  501.             vdata->view_line_count=vdata->view_file_size/16;
  502.             if (vdata->view_file_size<16) {
  503.                 vdata->view_line_count=1;
  504.             }
  505.             else if (vdata->view_file_size%16!=0) {
  506.                 ++vdata->view_line_count;
  507.             }
  508.         }
  509.         else {
  510.             vdata->view_line_count=countlines(vdata);
  511.         }
  512.     }
  513.  
  514.     vdata->view_last_line=vdata->view_line_count-vdata->view_lines_per_screen;
  515.     if (vdata->view_last_line<0) vdata->view_last_line=0;
  516.  
  517.     if (function==FUNC_ANSIREAD && !vdata->view_display_as_hex) {
  518.         vdata->view_display_as_ansi=1;
  519.  
  520.         ansiread_win.Width=vdata->view_char_width*vdata->view_font->tf_XSize;
  521.         ansiread_win.Height=vdata->view_font->tf_YSize*3;
  522.         ansiread_win.Screen=vdata->view_screen;
  523.  
  524.         if (!(vdata->view_ansiread_window=OpenWindow(&ansiread_win)))
  525.             vdata->view_display_as_ansi=0;
  526.         else {
  527.             SetFont(vdata->view_ansiread_window->RPort,vdata->view_font);
  528.             vdata->view_console_request.io_Data=(APTR)vdata->view_ansiread_window;
  529.             Delay(5);
  530.         }
  531.  
  532.         if (vdata->view_display_as_ansi) {
  533.             if (OpenDevice("console.device",0,(struct IORequest *)&vdata->view_console_request,0))
  534.                 vdata->view_display_as_ansi=0;
  535.             else {
  536.                 view_console_unit=(struct ConUnit *)vdata->view_console_request.io_Unit;
  537.                 for (a=0;a<MAXTABS;a++) {
  538.                     view_console_unit->cu_TabStops[a]=a*config->tabsize;
  539.                 }
  540.                 view_console_unit->cu_TabStops[MAXTABS-1]=0xffff;
  541.                 lsprintf(buf,"\x9b\x30\x20\x70\x9b%ld\x74",vdata->view_lines_per_screen);
  542.                 view_print(vdata,buf,1,strlen(buf));
  543.                 vdata->view_max_line_length=255;
  544.             }
  545.         }
  546.     }
  547.     else vdata->view_display_as_ansi=0;
  548.  
  549.     view_status_text(vdata,name);
  550.     vdata->view_file_name=name;
  551.     vdata->view_path_name=filename;
  552.     view_update_status(vdata);
  553.     view_penrp(vdata);
  554.  
  555.     vdata->view_scroll_width=vdata->view_char_width*vdata->view_font->tf_XSize;
  556.     view_displayall(vdata);
  557.     retcode=1;
  558.  
  559.     if (config->viewbits&VIEWBITS_TEXTBORDERS) {
  560.         FixSliderBody(vdata->view_window,&vdata->view_gadgets[VIEW_SCROLLGADGET],
  561.             vdata->view_line_count,vdata->view_lines_per_screen,1);
  562.         FixSliderPot(vdata->view_window,&vdata->view_gadgets[VIEW_SCROLLGADGET],
  563.             0,vdata->view_line_count,vdata->view_lines_per_screen,1);
  564.     }
  565.  
  566.     lsprintf(titlebuf,"%s - \"%s\"",globstring[STR_FILE],vdata->view_path_name);
  567.     SetWindowTitles(vdata->view_window,(char *)-1,titlebuf);
  568.  
  569.     vdata->view_window->WLayer->Flags|=LAYERBACKDROP;
  570.  
  571.     view_unbusy(vdata);
  572.  
  573.     if (initialsearch) {
  574.         strcpy(vdata->view_search_string,initialsearch);
  575.         view_search(vdata,1);
  576.     }
  577.  
  578.     FOREVER {
  579.         while (msg=(struct IntuiMessage *)GetMsg(vdata->view_window->UserPort)) {
  580.             class=msg->Class; code=msg->Code; qual=msg->Qualifier;
  581.             gadget=(struct Gadget *)msg->IAddress;
  582.             ReplyMsg((struct Message *)msg);
  583.  
  584.             switch (class) {
  585.                 case IDCMP_MOUSEMOVE:
  586.                     if (vdata->view_gadgets[VIEW_SCROLLGADGET].Flags&GFLG_SELECTED)
  587.                         view_fix_scroll_gadget(vdata);
  588.                     break;
  589.                 case IDCMP_MOUSEBUTTONS:
  590.                     if (code==SELECTDOWN) view_togglescroll(vdata);
  591.                     else if (code==MENUDOWN) {
  592.                         retcode=-1;
  593.                         goto cleanup;
  594.                     }
  595.                     break;
  596.                 case IDCMP_GADGETDOWN:
  597.                     if (vdata->view_scroll) {
  598.                         view_togglescroll(vdata);
  599.                         break;
  600.                     }
  601.                     gadgetid=gadget->GadgetID;
  602.                     switch (gadgetid) {
  603.                         case VIEW_SCROLLGADGET:
  604.                             view_fix_scroll_gadget(vdata);
  605.                             break;
  606.                         case VIEW_SCROLLUP:
  607.                         case VIEW_SCROLLDOWN:
  608.                             if (gadgetid==VIEW_SCROLLUP) a=view_lineup(vdata);
  609.                             else a=view_linedown(vdata);
  610.                             if (!a) break;
  611.                             Delay(5);
  612.                             FOREVER {
  613.                                 if (msg=(struct IntuiMessage *)GetMsg(vdata->view_window->UserPort)) {
  614.                                     if (msg->Class==IDCMP_GADGETUP ||
  615.                                         (msg->Class==IDCMP_MOUSEBUTTONS && msg->Code==SELECTUP))
  616.                                         break;
  617.                                     ReplyMsg((struct Message *)msg); msg=NULL;
  618.                                 }
  619.                                 if (gadgetid==VIEW_SCROLLUP) a=view_lineup(vdata);
  620.                                 else a=view_linedown(vdata);
  621.                                 if (!a) break;
  622.                             }
  623.                             if (msg) ReplyMsg((struct Message *)msg);
  624.                             break;
  625.                     }
  626.                     break;
  627.                 case IDCMP_GADGETUP:
  628.                     if (vdata->view_scroll) {
  629.                         view_togglescroll(vdata);
  630.                         break;
  631.                     }
  632.                     gadgetid=gadget->GadgetID;
  633. testgad:
  634.                     switch (gadgetid) {
  635.                         case VIEW_SCROLLGADGET:
  636.                             view_fix_scroll_gadget(vdata);
  637.                             break;
  638.                         case VIEW_PAGEUP:
  639.                             view_pageup(vdata);
  640.                             break;
  641.                         case VIEW_PAGEDOWN:
  642.                             view_pagedown(vdata);
  643.                             break;
  644.                         case VIEW_GOTOP:
  645.                             view_gotop(vdata);
  646.                             break;
  647.                         case VIEW_GOBOTTOM:
  648.                             view_gobottom(vdata);
  649.                             break;
  650.                         case VIEW_SEARCH:
  651.                             view_search(vdata,1);
  652.                             break;
  653.                         case VIEW_QUIT:
  654.                             goto cleanup;
  655.                             break;
  656.                         case VIEW_PRINT:
  657.                             view_checkprint(vdata,0);
  658.                             break;
  659.                         case VIEW_JUMPTOLINE:
  660.                         case VIEW_JUMPTOPERCENT:
  661.                             view_busy(vdata);
  662.                             buf[0]=0;
  663.                             if (gadgetid==VIEW_JUMPTOLINE) {
  664.                                 a=10;
  665.                                 b=STR_JUMP_TO_LINE;
  666.                             }
  667.                             else {
  668.                                 a=4;
  669.                                 b=STR_JUMP_TO_PERCENTAGE;
  670.                             }
  671.                             if (!(view_whatsit(vdata,globstring[b],a,buf)) || !buf[0]) {
  672.                                 view_unbusy(vdata);
  673.                                 break;
  674.                             }
  675.                             a=atoi(buf); if (a<0) a=0;
  676.                             if (gadgetid==VIEW_JUMPTOPERCENT)
  677.                                 a=((a+1)*(vdata->view_last_line))/100;
  678.                             if (a>vdata->view_last_line) a=vdata->view_last_line;
  679.  
  680.                             if (vdata->view_display_as_hex) {
  681.                                 if (vdata->view_text_offset!=a) {
  682.                                     vdata->view_text_offset=a;
  683.                                     view_displayall(vdata);
  684.                                 }
  685.                                 view_unbusy(vdata);
  686.                                 break;
  687.                             }
  688.  
  689.                             if (vdata->view_text_offset!=a) {
  690.                                 if (vdata->view_text_offset<a) {
  691.                                     if (a-vdata->view_text_offset<vdata->view_last_line-a) {
  692.                                         for (b=vdata->view_text_offset;b<a;b++) {
  693.                                             for (c=vdata->view_top_buffer_pos;c<vdata->view_file_size;c++)
  694.                                                 if (vdata->view_text_buffer[c]==10) break;
  695.                                             vdata->view_top_buffer_pos=c+1;
  696.                                         }
  697.                                     }
  698.                                     else {
  699.                                         vdata->view_text_offset=vdata->view_last_line;
  700.                                         vdata->view_top_buffer_pos=vdata->view_file_size;
  701.                                         for (c=0;c<vdata->view_lines_per_screen;c++) {
  702.                                             for (b=vdata->view_top_buffer_pos-2;b>=0;b--)
  703.                                                 if (vdata->view_text_buffer[b]==10) break;
  704.                                             vdata->view_top_buffer_pos=b+1;
  705.                                         }
  706.                                         for (b=a;b<vdata->view_text_offset;b++) {
  707.                                             for (c=vdata->view_top_buffer_pos-2;c>=0;c--)
  708.                                                 if (vdata->view_text_buffer[c]==10) break;
  709.                                             vdata->view_top_buffer_pos=c+1;
  710.                                         }
  711.                                     }
  712.                                 }
  713.                                 else {
  714.                                     if (vdata->view_text_offset-a<a) {
  715.                                         for (b=a;b<vdata->view_text_offset;b++) {
  716.                                             for (c=vdata->view_top_buffer_pos-2;c>=0;c--)
  717.                                                 if (vdata->view_text_buffer[c]==10) break;
  718.                                             vdata->view_top_buffer_pos=c+1;
  719.                                         }
  720.                                     }
  721.                                     else {
  722.                                         vdata->view_top_buffer_pos=0;
  723.                                         for (b=0;b<a;b++) {
  724.                                             for (c=vdata->view_top_buffer_pos;c<vdata->view_file_size;c++)
  725.                                                 if (vdata->view_text_buffer[c]==10) break;
  726.                                             vdata->view_top_buffer_pos=c+1;
  727.                                         }
  728.                                     }
  729.                                 }
  730.                                 vdata->view_text_offset=a;
  731.                                 view_displayall(vdata);
  732.                             }
  733.                             view_unbusy(vdata);
  734.                             break;
  735.                     }
  736.                     break;
  737.                 case IDCMP_RAWKEY:
  738.                     if (vdata->view_scroll && code!=0x40) {
  739.                         view_togglescroll(vdata);
  740.                         break;
  741.                     }
  742.                     switch (code) {
  743.                         case 0x45:
  744.                             retcode=-1;
  745.                         case 0x10:
  746.                         case 0x32:
  747.                             goto cleanup;
  748.                         case 0x35:
  749.                         case 0x1d:
  750.                             view_gobottom(vdata);
  751.                             break;
  752.                         case 0x14:
  753.                         case 0x3d:
  754.                             view_gotop(vdata);
  755.                             break;
  756.                         case 0x16:
  757.                         case 0x3f:
  758.                             view_pageup(vdata);
  759.                             break;
  760.                         case 0x22:
  761.                         case 0x1f:
  762.                             view_pagedown(vdata);
  763.                             break;
  764.                         case 0x21:
  765.                             view_search(vdata,1);
  766.                             break;
  767.                         case 0x26:
  768.                             gadgetid=VIEW_JUMPTOLINE;
  769.                             goto testgad;
  770.                         case 0x36:
  771.                             view_search(vdata,0);
  772.                             break;
  773.                         case 0xc0:
  774.                             view_togglescroll(vdata);
  775.                             break;
  776.                         case CURSOR_UP:
  777.                         case 0x3e:
  778.                             if (vdata->view_line_count<=vdata->view_lines_per_screen) break;
  779.                             view_readkeys(view_req,key_matrix);
  780.                             if (!(qual&IEQUALIFIER_REPEAT) ||
  781.                                 key_matrix[9]&16 || key_matrix[7]&64) {
  782.                                 if (qual&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) view_pageup(vdata);
  783.                                 else if (qual&IEQUALIFIER_CONTROL) view_gotop(vdata);
  784.                                 else view_lineup(vdata);
  785.                             }
  786.                             break;
  787.                         case CURSOR_DOWN:
  788.                         case 0x1e:
  789.                             if (vdata->view_line_count<=vdata->view_lines_per_screen) break;
  790.                             view_readkeys(view_req,key_matrix);
  791.                             if (!(qual&IEQUALIFIER_REPEAT) ||
  792.                                 key_matrix[9]&32 || key_matrix[3]&64) {
  793.                                 if (qual&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) view_pagedown(vdata);
  794.                                 else if (qual&IEQUALIFIER_CONTROL) view_gobottom(vdata);
  795.                                 else view_linedown(vdata);
  796.                             }
  797.                             break;
  798.                         case 0x19: view_checkprint(vdata,0); break;
  799.                         case 0x33: view_checkprint(vdata,1); break;
  800.                     }
  801.                     break;
  802.             }
  803.         }
  804.         if (IntuitionBase->ActiveWindow==vdata->view_window && vdata->view_scroll) {
  805.             a=vdata->view_window->MouseY;
  806.             if (a<scroll_pos_4) {
  807.                 if (a<scroll_pos_1) scroll_speed=1;
  808.                 else if (a<scroll_pos_2) scroll_speed=vdata->view_font->tf_YSize/4;
  809.                 else if (a<scroll_pos_3) scroll_speed=vdata->view_font->tf_YSize/2;
  810.                 else if (a<scroll_pos_4-10) scroll_speed=vdata->view_font->tf_YSize;
  811.                 else scroll_speed=0;
  812.  
  813.                 if (scroll_speed>0 && vdata->view_line_count>vdata->view_lines_per_screen) {
  814.                     --vdata->view_text_offset;
  815.                     if (vdata->view_text_offset<0) {
  816.                         vdata->view_text_offset=0;
  817.                         view_togglescroll(vdata);
  818.                     }
  819.                     else {
  820.                         if (vdata->view_scroll_dir==1) view_display(vdata,scroll_speed,1);
  821.                         else view_display(vdata,scroll_speed,0);
  822.                     }
  823.                     vdata->view_scroll_dir=-1;
  824.                 }
  825.             }
  826.             else {
  827.                 if (a>scroll_pos_7) scroll_speed=1;
  828.                 else if (a>scroll_pos_6) scroll_speed=vdata->view_font->tf_YSize/4;
  829.                 else if (a>scroll_pos_5) scroll_speed=vdata->view_font->tf_YSize/2;
  830.                 else if (a>scroll_pos_4+10) scroll_speed=vdata->view_font->tf_YSize;
  831.                 else scroll_speed=0;
  832.                 if (scroll_speed>0 && vdata->view_line_count>vdata->view_lines_per_screen) {
  833.                     ++vdata->view_text_offset;
  834.                     vdata->view_scroll_dir=1;
  835.                     if (vdata->view_text_offset>vdata->view_last_line) {
  836.                         vdata->view_text_offset=vdata->view_last_line;
  837.                         view_togglescroll(vdata);
  838.                     }
  839.                     else view_display(vdata,scroll_speed,0);
  840.                 }
  841.             }
  842.             continue;
  843.         }
  844.         Wait(1<<vdata->view_window->UserPort->mp_SigBit);
  845.     }
  846.  
  847. cleanup:
  848.     if (vdata->view_text_buffer)
  849.         FreeMem(vdata->view_text_buffer,vdata->view_buffer_size);
  850.     if (view_console_unit)
  851.         CloseDevice((struct IORequest *)&vdata->view_console_request);
  852.     if (vdata->view_ansiread_window) {
  853.         CloseWindow(vdata->view_ansiread_window);
  854.         vdata->view_ansiread_window=NULL;
  855.     }
  856.     view_clearhilite(vdata,0);
  857.     if (!viewdata) {
  858.         cleanupviewfile(vdata);
  859.         FreeMem(vdata,sizeof(struct ViewData));
  860.     }
  861.     else {
  862.         SetBusyPointer(vdata->view_window);
  863.         vdata->view_window->WLayer->Flags&=~LAYERBACKDROP;
  864.     }
  865.  
  866. view_end:
  867.     if (view_req) {
  868.         CloseDevice((struct IORequest *)view_req);
  869.         LDeleteExtIO((struct IORequest *)view_req);
  870.     }
  871.     if (view_port) LDeletePort(view_port);
  872.     my_startup_message->command=retcode;
  873.     Forbid();
  874.     ReplyMsg((struct Message *)my_startup_message);
  875.     return;
  876. }
  877.  
  878. void cleanupviewfile(vdata)
  879. struct ViewData *vdata;
  880. {
  881.     if (vdata->view_screen) {
  882.         ScreenToBack(vdata->view_screen);
  883.         if (vdata->view_window) CloseWindow(vdata->view_window);
  884.         CloseScreen(vdata->view_screen);
  885.         if (vdata->view_font) CloseFont(vdata->view_font);
  886.     }
  887.     LFreeRemember(&vdata->view_memory);
  888. }
  889.  
  890. void view_display(vdata,scroll_speed,w)
  891. struct ViewData *vdata;
  892. int scroll_speed,w;
  893. {
  894.     int a,b,c,d;
  895.  
  896.     view_clearhilite(vdata,1);
  897.     view_clearsearch(vdata);
  898.  
  899.     d=vdata->view_font->tf_YSize/scroll_speed;
  900.  
  901.     if (vdata->view_text_offset<vdata->view_old_offset) {
  902.         --vdata->view_old_offset;
  903.         a=0;
  904.         while (a<vdata->view_font->tf_YSize) {
  905.             if (a+d>vdata->view_font->tf_YSize) d=vdata->view_font->tf_YSize-a;
  906.             view_doscroll(vdata,-d,vdata->view_scroll_width);
  907.             a+=d;
  908.         }
  909.         if (vdata->view_display_as_hex) {
  910.             view_print(vdata,&vdata->view_text_buffer[vdata->view_text_offset*16],0,16);
  911.             view_update_status(vdata);
  912.             return;
  913.         }
  914.         else {
  915.             for (a=vdata->view_top_buffer_pos-2,b=0;a>=0;a--,b++) {
  916.                 if (vdata->view_text_buffer[a]==10 || b==vdata->view_max_line_length)
  917.                     break;
  918.             }
  919.             c=vdata->view_top_buffer_pos-a-1;
  920.             vdata->view_top_buffer_pos=a+1;
  921.             for (a=vdata->view_bottom_buffer_pos-2,b=0;a>=0;a--,b++) {
  922.                 if (vdata->view_text_buffer[a]==10 || b==vdata->view_max_line_length)
  923.                     break;
  924.             }
  925.             vdata->view_bottom_buffer_pos=a+1;
  926.         }
  927.         if (vdata->view_top_buffer_pos+c>vdata->view_file_size)
  928.             c=vdata->view_file_size-vdata->view_top_buffer_pos;
  929.         view_print(vdata,&vdata->view_text_buffer[vdata->view_top_buffer_pos],0,c);
  930.     }
  931.     else if (vdata->view_text_offset>vdata->view_old_offset) {
  932.         ++vdata->view_old_offset;
  933.         a=0;
  934.         while (a<vdata->view_font->tf_YSize) {
  935.             if (a+d>vdata->view_font->tf_YSize) d=vdata->view_font->tf_YSize-a;
  936.             view_doscroll(vdata,d,vdata->view_scroll_width);
  937.             a+=d;
  938.         }
  939.         if (!w && !vdata->view_display_as_hex) {
  940.             for (a=vdata->view_top_buffer_pos,b=0;a<vdata->view_file_size;a++,b++) {
  941.                 if (vdata->view_text_buffer[a]==10 || b==vdata->view_max_line_length)
  942.                     break;
  943.             }
  944.             vdata->view_top_buffer_pos=a+1;
  945.         }
  946.         if (!vdata->view_display_as_hex) {
  947.             for (a=vdata->view_bottom_buffer_pos,b=0;a<vdata->view_file_size;a++,b++) {
  948.                 if (vdata->view_text_buffer[a]==10 || b==vdata->view_max_line_length)
  949.                     break;
  950.             }
  951.             vdata->view_bottom_buffer_pos=a+1;
  952.         }
  953.         if (vdata->view_bottom_buffer_pos<vdata->view_file_size) {
  954.             if (vdata->view_display_as_hex) {
  955.                 view_print(vdata,
  956.                     &vdata->view_text_buffer[(vdata->view_text_offset+vdata->view_lines_per_screen-1)*16],
  957.                     vdata->view_lines_per_screen-1,16);
  958.             }
  959.             else {
  960.                 for (a=vdata->view_bottom_buffer_pos,b=0;a<vdata->view_file_size;a++,b++) {
  961.                     if (vdata->view_text_buffer[a]==10 || b==vdata->view_max_line_length)
  962.                     break;
  963.                 }
  964.                 c=a-vdata->view_bottom_buffer_pos+1;
  965.                 if (vdata->view_bottom_buffer_pos+c>vdata->view_file_size)
  966.                     c=vdata->view_file_size-vdata->view_bottom_buffer_pos;
  967.                 view_print(vdata,
  968.                     &vdata->view_text_buffer[vdata->view_bottom_buffer_pos],
  969.                     vdata->view_lines_per_screen-1,c);
  970.             }
  971.         }
  972.     }
  973.     view_update_status(vdata);
  974. }
  975.  
  976. void view_displayall(vdata)
  977. struct ViewData *vdata;
  978. {
  979.     int a,c,d,f;
  980.  
  981.     SetAPen(vdata->view_rastport,vdata->view_colour_table[PEN_TEXTBACKGROUND]);
  982.     RectFill(vdata->view_rastport,
  983.         vdata->view_display_left,
  984.         vdata->view_display_top,
  985.         vdata->view_display_right,
  986.         vdata->view_display_bottom);
  987.     SetAPen(vdata->view_rastport,vdata->view_colour_table[PEN_TEXT]);
  988.  
  989.     view_clearhilite(vdata,0);
  990.     view_clearsearch(vdata);
  991.  
  992.     f=d=vdata->view_bottom_buffer_pos=vdata->view_top_buffer_pos;
  993.  
  994.     if (vdata->view_display_as_hex) {
  995.         d=vdata->view_text_offset*16;
  996.         for (a=0;a<vdata->view_lines_per_screen;a++) {
  997.             if (d<vdata->view_file_size)
  998.                 view_print(vdata,&vdata->view_text_buffer[d],a,16);
  999.             d+=16;
  1000.         }
  1001.     }
  1002.     else {
  1003.         for (a=0;a<vdata->view_lines_per_screen;a++) {
  1004.             for (c=0;c<vdata->view_max_line_length;c++) {
  1005.                 if (vdata->view_text_buffer[f]==10) break;
  1006.                 ++f;
  1007.             }
  1008.             ++f;
  1009.             if (d+c+1>vdata->view_file_size)
  1010.                 c=vdata->view_file_size-d-1;
  1011.             if (d<vdata->view_file_size)
  1012.                 view_print(vdata,&vdata->view_text_buffer[d],a,c+1);
  1013.             d=f;
  1014.             if (a<vdata->view_lines_per_screen-1)
  1015.                 vdata->view_bottom_buffer_pos=d;
  1016.         }
  1017.     }
  1018.  
  1019.     vdata->view_old_offset=vdata->view_text_offset;
  1020.     view_update_status(vdata);
  1021. }
  1022.  
  1023. void view_print(vdata,str,y,len)
  1024. struct ViewData *vdata;
  1025. char *str;
  1026. int y,len;
  1027. {
  1028.     unsigned char textbuf[300];
  1029.  
  1030.     if (vdata->view_display_as_ansi) {
  1031.         if (len>0) {
  1032.             if (str[len-1]=='\n') --len;
  1033.             vdata->view_console_request.io_Data=(APTR)"\x9b;0m\f";
  1034.             vdata->view_console_request.io_Length=5;
  1035.             vdata->view_console_request.io_Command=CMD_WRITE;
  1036.             DoIO((struct IORequest *)&vdata->view_console_request);
  1037.  
  1038.             vdata->view_console_request.io_Data=(APTR)str;
  1039.             vdata->view_console_request.io_Length=len;
  1040.             vdata->view_console_request.io_Command=CMD_WRITE;
  1041.             DoIO((struct IORequest *)&vdata->view_console_request);
  1042.  
  1043.             if (y>-1) {
  1044.                 ClipBlit(vdata->view_ansiread_window->RPort,0,0,
  1045.                     vdata->view_rastport,
  1046.                     vdata->view_display_left,
  1047.                     vdata->view_display_top+(y*vdata->view_font->tf_YSize),
  1048.                     vdata->view_ansiread_window->Width,
  1049.                     vdata->view_font->tf_YSize,0xc0);
  1050.             }
  1051.         }
  1052.     }
  1053.     else {
  1054.         Move(vdata->view_rastport,
  1055.             vdata->view_display_left,
  1056.             vdata->view_display_top+(y*vdata->view_font->tf_YSize)+vdata->view_font->tf_Baseline);
  1057.  
  1058.         if (vdata->view_display_as_hex) {
  1059.             view_makeuphex(vdata,str,textbuf,vdata->view_text_offset+y);
  1060.             len=vdata->view_char_width;
  1061.         }
  1062.         else {
  1063.             if (len>vdata->view_char_width) len=vdata->view_char_width;
  1064.             CopyMem(str,(char *)textbuf,len);
  1065.             if (textbuf[len-1]==10) textbuf[len-1]=' ';
  1066.         }
  1067.         if (len>0) Text(vdata->view_rastport,(char *)textbuf,len);
  1068.     }
  1069. }
  1070.  
  1071. void view_update_status(vdata)
  1072. struct ViewData *vdata;
  1073. {
  1074.     char textbuf[80];
  1075.     int a;
  1076.  
  1077.     view_pensrp(vdata);
  1078.     Move(vdata->view_rastport,
  1079.         vdata->view_window->Width-((vdata->view_font->tf_XSize*49)+14),
  1080.         vdata->view_status_bar_ypos+vdata->view_font->tf_Baseline);
  1081.  
  1082.     if (vdata->view_line_count<=vdata->view_lines_per_screen)
  1083.         a=100;
  1084.     else a=(vdata->view_text_offset*100)/vdata->view_last_line;
  1085.  
  1086.     lsprintf(textbuf,
  1087.         "%-6ld > %-6ld / %-6ld   %-3ld%%",vdata->view_text_offset,
  1088.         (vdata->view_text_offset+vdata->view_lines_per_screen>vdata->view_line_count)?
  1089.             vdata->view_line_count:vdata->view_text_offset+vdata->view_lines_per_screen,
  1090.         vdata->view_line_count,a);
  1091.  
  1092.     Text(vdata->view_rastport,textbuf,31);
  1093.  
  1094.     if (config->viewbits&VIEWBITS_TEXTBORDERS && vdata->view_scroll_bar)
  1095.         FixSliderPot(vdata->view_window,
  1096.             &vdata->view_gadgets[VIEW_SCROLLGADGET],
  1097.             vdata->view_text_offset,
  1098.             vdata->view_line_count,
  1099.             vdata->view_lines_per_screen,1);
  1100.  
  1101.     view_penrp(vdata);
  1102. }
  1103.  
  1104. void view_pensrp(vdata)
  1105. struct ViewData *vdata;
  1106. {
  1107.     SetAPen(vdata->view_rastport,vdata->view_colour_table[VIEWPEN_STATUSTEXT]);
  1108.     SetBPen(vdata->view_rastport,vdata->view_colour_table[VIEWPEN_STATUSBACKGROUND]);
  1109.     SetDrMd(vdata->view_rastport,JAM2);
  1110. }
  1111.  
  1112. void view_penrp(vdata)
  1113. struct ViewData *vdata;
  1114. {
  1115.     SetAPen(vdata->view_rastport,vdata->view_colour_table[PEN_TEXT]);
  1116.     SetBPen(vdata->view_rastport,vdata->view_colour_table[PEN_TEXTBACKGROUND]);
  1117.     SetDrMd(vdata->view_rastport,JAM1);
  1118. }
  1119.  
  1120. void view_pageup(vdata)
  1121. struct ViewData *vdata;
  1122. {
  1123.     int a,b,c;
  1124.  
  1125.     if (vdata->view_text_offset==0) return;
  1126.     vdata->view_text_offset-=vdata->view_lines_per_screen;
  1127.     if (vdata->view_text_offset<0) {
  1128.         vdata->view_text_offset=0;
  1129.         vdata->view_top_buffer_pos=0;
  1130.     }
  1131.     else if (!vdata->view_display_as_hex) {
  1132.         for (c=0;c<vdata->view_lines_per_screen;c++) {
  1133.             for (a=vdata->view_top_buffer_pos-2,b=0;a>=0;a--,b++) {
  1134.                 if (vdata->view_text_buffer[a]==10 || b==vdata->view_max_line_length)
  1135.                     break;
  1136.             }
  1137.             vdata->view_top_buffer_pos=a+1;
  1138.         }
  1139.     }
  1140.     view_displayall(vdata);
  1141. }
  1142.  
  1143. void view_pagedown(vdata)
  1144. struct ViewData *vdata;
  1145. {
  1146.     int a,b,c;
  1147.  
  1148.     if (vdata->view_text_offset==vdata->view_last_line ||
  1149.         vdata->view_line_count<=vdata->view_lines_per_screen) return;
  1150.  
  1151.     vdata->view_text_offset+=vdata->view_lines_per_screen;
  1152.  
  1153.     if (vdata->view_text_offset>vdata->view_last_line) {
  1154.         vdata->view_text_offset=vdata->view_last_line;
  1155.  
  1156.         if (!vdata->view_display_as_hex) {
  1157.             vdata->view_top_buffer_pos=vdata->view_file_size;
  1158.             for (c=0;c<vdata->view_lines_per_screen;c++) {
  1159.                 for (a=vdata->view_top_buffer_pos-2,b=0;a>=0;a--,b++) {
  1160.                     if (vdata->view_text_buffer[a]==10 || b==vdata->view_max_line_length)
  1161.                         break;
  1162.                 }
  1163.                 vdata->view_top_buffer_pos=a+1;
  1164.             }
  1165.         }
  1166.     }
  1167.     else {
  1168.         if (!vdata->view_display_as_hex) {
  1169.             vdata->view_top_buffer_pos=vdata->view_bottom_buffer_pos;
  1170.             for (a=vdata->view_top_buffer_pos,b=0;a<vdata->view_file_size;a++,b++) {
  1171.                 if (vdata->view_text_buffer[a]==10 || b==vdata->view_max_line_length)
  1172.                     break;
  1173.             }
  1174.             vdata->view_top_buffer_pos=a+1;
  1175.         }
  1176.     }
  1177.     view_displayall(vdata);
  1178. }
  1179.  
  1180. void view_gotop(vdata)
  1181. struct ViewData *vdata;
  1182. {
  1183.     if (vdata->view_text_offset) {
  1184.         vdata->view_text_offset=0;
  1185.         vdata->view_top_buffer_pos=0;
  1186.         view_displayall(vdata);
  1187.     }
  1188. }
  1189.  
  1190. void view_gobottom(vdata)
  1191. struct ViewData *vdata;
  1192. {
  1193.     int a,b,c;
  1194.  
  1195.     if (vdata->view_text_offset!=vdata->view_last_line &&
  1196.         vdata->view_line_count>vdata->view_lines_per_screen) {
  1197.  
  1198.         vdata->view_text_offset=vdata->view_last_line;
  1199.  
  1200.         if (!vdata->view_display_as_hex) {
  1201.             vdata->view_top_buffer_pos=vdata->view_file_size;
  1202.  
  1203.             for (c=0;c<vdata->view_lines_per_screen;c++) {
  1204.                 for (a=vdata->view_top_buffer_pos-2,b=0;a>=0;a--,b++) {
  1205.                     if (vdata->view_text_buffer[a]==10 || b==vdata->view_max_line_length)
  1206.                         break;
  1207.                 }
  1208.                 vdata->view_top_buffer_pos=a+1;
  1209.             }
  1210.         }
  1211.         view_displayall(vdata);
  1212.     }
  1213. }
  1214.  
  1215. void view_search(vdata,ask)
  1216. struct ViewData *vdata;
  1217. int ask;
  1218. {
  1219.     int a,off,bpos,c,d,e,f,mlen;
  1220.     char temp[80];
  1221.  
  1222.     status_haveaborted=0;
  1223.     view_clearhilite(vdata,1);
  1224.  
  1225.     if (!vdata->view_search_string[0]) ask=1;
  1226.     strcpy(temp,vdata->view_search_string);
  1227.     view_busy(vdata);
  1228.  
  1229.     if (ask) {
  1230.         if (!(get_search_data(vdata->view_search_string,&vdata->view_search_flags,
  1231.             vdata->view_window,vdata->view_font))) {
  1232.             view_unbusy(vdata);
  1233.             return;
  1234.         }
  1235.     }
  1236.  
  1237.     if (!vdata->view_search_string[0]) {
  1238.         view_unbusy(vdata);
  1239.         return;
  1240.     }
  1241.  
  1242.     if (LStrCmpI(temp,vdata->view_search_string)) view_clearsearch(vdata);
  1243.  
  1244.     if (vdata->view_display_as_hex) {
  1245.         if (vdata->view_search_offset!=-1) {
  1246.             a=(vdata->view_search_offset*16)+vdata->view_search_charoffset;
  1247.             off=vdata->view_search_offset;
  1248.         }
  1249.         else {
  1250.             a=vdata->view_text_offset*16;
  1251.             off=vdata->view_text_offset;
  1252.         }
  1253.     }
  1254.     else {
  1255.         if (vdata->view_search_charoffset!=-1) {
  1256.             a=vdata->view_search_charoffset;
  1257.             off=vdata->view_search_offset;
  1258.         }
  1259.         else {
  1260.             a=vdata->view_top_buffer_pos;
  1261.             off=vdata->view_text_offset;
  1262.         }
  1263.     }
  1264. dosearch:
  1265.     if ((typesearch(0,vdata->view_search_string,
  1266.         vdata->view_search_flags,&vdata->view_text_buffer[a],
  1267.         vdata->view_file_size-a))>-1) {
  1268.  
  1269.         if (vdata->view_display_as_hex) {
  1270.             bpos=search_found_position-vdata->view_text_buffer;
  1271.             off=bpos/16; c=bpos%16;
  1272.             mlen=search_found_size;
  1273.             if (vdata->view_pick_charoffset!=bpos) {
  1274.                 if (!(vdata->view_text_offset==vdata->view_last_line ||
  1275.                     vdata->view_line_count<vdata->view_lines_per_screen ||
  1276.                     vdata->view_text_offset>vdata->view_last_line ||
  1277.                     off<vdata->view_text_offset+vdata->view_lines_per_screen)) {
  1278.  
  1279.                     vdata->view_text_offset=
  1280.                         vdata->view_search_offset=off;
  1281.  
  1282.                     if (vdata->view_text_offset>vdata->view_last_line)
  1283.                         view_gobottom(vdata);
  1284.                     else view_displayall(vdata);
  1285.                 }
  1286.                 else if (vdata->view_text_offset>vdata->view_last_line) {
  1287.                     view_gobottom(vdata);
  1288.                 }
  1289.  
  1290.                 d=(10+(c*2)+(c/4))*vdata->view_font->tf_XSize;
  1291.                 if ((f=c+mlen)>16) f=16;
  1292.                 e=(10+(f*2)+(f/4))*vdata->view_font->tf_XSize;
  1293.                 if ((f%4)==0) e-=vdata->view_font->tf_XSize;
  1294.  
  1295.                 for (a=0;a<2;a++) {
  1296.                     view_viewhilite(vdata,
  1297.                         d,(off-vdata->view_text_offset)*vdata->view_font->tf_YSize,e-1,
  1298.                         (off-vdata->view_text_offset)*vdata->view_font->tf_YSize+(vdata->view_font->tf_YSize-1));
  1299.                     d=(46+c)*vdata->view_font->tf_XSize;
  1300.                     e=(46+f)*vdata->view_font->tf_XSize;
  1301.                 }
  1302.                 vdata->view_pick_offset=-1;
  1303.                 vdata->view_pick_charoffset=bpos;
  1304.                 vdata->view_search_offset=off;
  1305.                 vdata->view_search_charoffset=c+1;
  1306.             }
  1307.             else {
  1308.                 a=bpos+1;
  1309.                 goto dosearch;
  1310.             }
  1311.         }
  1312.         else {
  1313.             off+=search_found_lines;
  1314.             bpos=search_last_line_pos+a;
  1315.             if (vdata->view_pick_offset!=bpos && vdata->view_pick_charoffset!=off) {
  1316.                 if (vdata->view_text_offset==vdata->view_last_line ||
  1317.                     vdata->view_line_count<vdata->view_lines_per_screen ||
  1318.                     off<vdata->view_text_offset+vdata->view_lines_per_screen ||
  1319.                     off>vdata->view_last_line) {
  1320.  
  1321.                     if (off>vdata->view_last_line) view_gobottom(vdata);
  1322.  
  1323.                     vdata->view_search_charoffset=bpos;
  1324.                     vdata->view_search_offset=off;
  1325.  
  1326.                     view_viewhilite(vdata,
  1327.                         0,(off-vdata->view_text_offset)*vdata->view_font->tf_YSize,
  1328.                         vdata->view_char_width*vdata->view_font->tf_XSize,
  1329.                         (off-vdata->view_text_offset)*vdata->view_font->tf_YSize+(vdata->view_font->tf_YSize-1));
  1330.                 }
  1331.                 else {
  1332.                     vdata->view_top_buffer_pos=bpos;
  1333.                     vdata->view_text_offset=off;
  1334.                     view_displayall(vdata);
  1335.                     view_viewhilite(vdata,
  1336.                         0,0,
  1337.                         vdata->view_char_width*vdata->view_font->tf_XSize,
  1338.                         vdata->view_font->tf_YSize-1);
  1339.                 }
  1340.                 vdata->view_pick_offset=bpos;
  1341.                 vdata->view_pick_charoffset=off;
  1342.             }
  1343.             else {
  1344.                 for (a=bpos;a<vdata->view_file_size;a++) {
  1345.                     if (vdata->view_text_buffer[a]==10)
  1346.                         break;
  1347.                 }
  1348.                 ++a; ++off;
  1349.                 goto dosearch;
  1350.             }
  1351.         }
  1352.     }
  1353.     else {
  1354.         view_clearsearch(vdata);
  1355.         view_simplerequest(vdata,globstring[STR_STRING_NOT_FOUND],globstring[STR_CONTINUE],NULL);
  1356.     }
  1357.     view_unbusy(vdata);
  1358.     return;
  1359. }
  1360.  
  1361. void view_busy(vdata)
  1362. struct ViewData *vdata;
  1363. {
  1364.     if (!vdata->view_window->Pointer) SetBusyPointer(vdata->view_window);
  1365.     if (!vdata->view_window->FirstRequest) {
  1366.         InitRequester(&vdata->view_busy_request);
  1367.         Request(&vdata->view_busy_request,vdata->view_window);
  1368.     }
  1369. }
  1370.  
  1371. void view_unbusy(vdata)
  1372. struct ViewData *vdata;
  1373. {
  1374.     ClearPointer(vdata->view_window);
  1375.     if (vdata->view_window->FirstRequest)
  1376.         EndRequest(&vdata->view_busy_request,vdata->view_window);
  1377. }
  1378.  
  1379. void view_doscroll(vdata,dy,w)
  1380. struct ViewData *vdata;
  1381. int dy,w;
  1382. {
  1383.     if (!vdata->view_display_as_ansi)
  1384.         SetWrMsk(vdata->view_rastport,vdata->view_colour_table[PEN_TEXT]);
  1385.     ScrollRaster(vdata->view_rastport,0,dy,
  1386.         vdata->view_display_left,
  1387.         vdata->view_display_top,
  1388.         vdata->view_display_left+w,
  1389.         vdata->view_display_top+vdata->view_display_height-1);
  1390.     if (!vdata->view_display_as_ansi)
  1391.         SetWrMsk(vdata->view_rastport,0xff);
  1392. }
  1393.  
  1394. view_lineup(vdata)
  1395. struct ViewData *vdata;
  1396. {
  1397.     if (vdata->view_text_offset==0) return(0);
  1398.     --vdata->view_text_offset;
  1399.     if (vdata->view_scroll_dir==1)
  1400.         view_display(vdata,1,1);
  1401.     else view_display(vdata,1,0);
  1402.     vdata->view_scroll_dir=-1;
  1403.     return(1);
  1404. }
  1405.  
  1406. view_linedown(vdata)
  1407. struct ViewData *vdata;
  1408. {
  1409.     if (vdata->view_text_offset>=vdata->view_last_line) return(0);
  1410.     ++vdata->view_text_offset;
  1411.     vdata->view_scroll_dir=1;
  1412.     view_display(vdata,1,0);
  1413.     return(1);
  1414. }
  1415.  
  1416. void view_status_text(vdata,str)
  1417. struct ViewData *vdata;
  1418. char *str;
  1419. {
  1420.     SetAPen(vdata->view_rastport,vdata->view_colour_table[VIEWPEN_STATUSBACKGROUND]);
  1421.     RectFill(vdata->view_rastport,
  1422.         2,
  1423.         vdata->view_status_bar_ypos,
  1424.         vdata->view_window->Width-((vdata->view_font->tf_XSize*18)+3),
  1425.         vdata->view_window->Height-2);
  1426.  
  1427.     view_pensrp(vdata);
  1428.  
  1429.     if (str) {
  1430.         Move(vdata->view_rastport,2,vdata->view_status_bar_ypos+vdata->view_font->tf_Baseline);
  1431.         Text(vdata->view_rastport,str,strlen(str));
  1432.     }
  1433. }
  1434.  
  1435. void view_printtext(vdata,state)
  1436. struct ViewData *vdata;
  1437. int state;
  1438. {
  1439.     int out,a,tb;
  1440.     char temp[60],*str;
  1441.     unsigned char buf1[80];
  1442.  
  1443.     status_haveaborted=0;
  1444.  
  1445.     if (state==0 && !vdata->view_display_as_hex) {
  1446.         struct DOpusArgsList print_args;
  1447.  
  1448.         print_args.single_file=vdata->view_path_name;
  1449.         print_args.file_window=-1;
  1450.         print_args.file_list=NULL;
  1451.         print_args.last_select=NULL;
  1452.  
  1453.         dopus_print(0,&print_args,0,vdata->view_port_name,vdata);
  1454.         return;
  1455.     }
  1456.  
  1457.     if (!(out=Open("PRT:",MODE_NEWFILE))) {
  1458.         view_simplerequest(vdata,globstring[STR_CANT_OPEN_PRINTER],globstring[STR_CONTINUE],NULL);
  1459.         return;
  1460.     }
  1461.     if (!vdata->view_display_as_hex) {
  1462.         char *print_ptr;
  1463.         int print_size;
  1464.  
  1465.         if (vdata->view_bottom_buffer_pos>=vdata->view_file_size) {
  1466.             print_size=vdata->view_file_size;
  1467.             print_ptr=vdata->view_text_buffer;
  1468.         }
  1469.         else {
  1470.             for (a=vdata->view_bottom_buffer_pos;a<vdata->view_file_size;a++) {
  1471.                 if (vdata->view_text_buffer[a]==10) break;
  1472.             }
  1473.             print_size=a-vdata->view_top_buffer_pos+1;
  1474.             print_ptr=&vdata->view_text_buffer[vdata->view_top_buffer_pos];
  1475.         }
  1476.  
  1477.         if ((Write(out,print_ptr,print_size))<print_size) {
  1478.             Close(out);
  1479.             lsprintf(temp,globstring[STR_ERROR_PRINTING_FILE],IoErr());
  1480.             view_simplerequest(vdata,temp,globstring[STR_CONTINUE],NULL);
  1481.             return;
  1482.         }
  1483.     }
  1484.     else {
  1485.         if (state==0) {
  1486.             str=vdata->view_text_buffer;
  1487.             for (a=0;a<vdata->view_line_count;a++) {
  1488.                 view_makeuphex(vdata,str,buf1,a);
  1489.                 if ((Write(out,(char *)buf1,63))<63) {
  1490.                     Close(out);
  1491.                     lsprintf(temp,globstring[STR_ERROR_PRINTING_FILE],IoErr());
  1492.                     view_simplerequest(vdata,temp,globstring[STR_CONTINUE],NULL);
  1493.                     return;
  1494.                 }
  1495.                 str+=16;
  1496.                 if (status_haveaborted) break;
  1497.             }
  1498.         }
  1499.         else {
  1500.             str=&vdata->view_text_buffer[vdata->view_text_offset*16];
  1501.             tb=vdata->view_text_offset*16;
  1502.             for (a=0;a<vdata->view_lines_per_screen;a++) {
  1503.                 view_makeuphex(vdata,str,buf1,vdata->view_text_offset+a);
  1504.                 if ((Write(out,(char *)buf1,63))<63) {
  1505.                     Close(out);
  1506.                     lsprintf(temp,globstring[STR_ERROR_PRINTING_FILE],IoErr());
  1507.                     view_simplerequest(vdata,temp,globstring[STR_CONTINUE],NULL);
  1508.                     return;
  1509.                 }
  1510.                 str+=16; tb+=16;
  1511.                 if (tb>vdata->view_file_size || status_haveaborted) break;
  1512.             }
  1513.         }
  1514.     }
  1515.     Close(out);
  1516.     return;
  1517. }
  1518.  
  1519. void view_checkprint(vdata,code)
  1520. struct ViewData *vdata;
  1521. int code;
  1522. {
  1523.     view_busy(vdata);
  1524.     if ((code==0 && !vdata->view_display_as_hex) ||
  1525.         (view_simplerequest(vdata,globstring[STR_READY_PRINTER],
  1526.             str_okaystring,str_cancelstring,NULL))) view_printtext(vdata,code);
  1527.     view_unbusy(vdata);
  1528. }
  1529.  
  1530. void view_makeuphex(vdata,hex,textbuf,line)
  1531. struct ViewData *vdata;
  1532. char *hex;
  1533. unsigned char *textbuf;
  1534. int line;
  1535. {
  1536.     unsigned char buf2[17];
  1537.     unsigned int buf3[17];
  1538.     int at,b,c,e;
  1539.  
  1540.     if (vdata->view_last_char && hex>=vdata->view_last_char)
  1541.         b=vdata->view_last_charpos;
  1542.     else b=16;
  1543.     for (at=0;at<b;at++) {
  1544.         if (!isprint(hex[at])) buf2[at]='.';
  1545.         else buf2[at]=hex[at];
  1546.         buf3[at]=(unsigned int)((unsigned char)hex[at]);
  1547.     }
  1548.     if (vdata->view_last_char && hex>=vdata->view_last_char) {
  1549.         for (at=b;at<16;at++) {
  1550.             buf2[at]=' ';
  1551.             buf3[at]=0;
  1552.         }
  1553.         e=b/4; c=10+(b*2)+e;
  1554.     }
  1555.     else c=-1;
  1556.     buf2[16]=0;
  1557.     lsprintf((char *)textbuf,
  1558.         "%08lx: %02lx%02lx%02lx%02lx %02lx%02lx%02lx%02lx %02lx%02lx%02lx%02lx \
  1559. %02lx%02lx%02lx%02lx %s\n",line*16,
  1560.         buf3[0],buf3[1],buf3[2],buf3[3],buf3[4],buf3[5],buf3[6],buf3[7],
  1561.         buf3[8],buf3[9],buf3[10],buf3[11],buf3[12],buf3[13],buf3[14],buf3[15],
  1562.         buf2);
  1563.     if (c>-1) {
  1564.         for (b=c;b<46;b++)
  1565.             textbuf[b]=' ';
  1566.     }
  1567. }
  1568.  
  1569. void view_togglescroll(vdata)
  1570. struct ViewData *vdata;
  1571. {
  1572.     if (vdata->view_scroll) {
  1573.         vdata->view_scroll=0;
  1574.         ClearPointer(vdata->view_window);
  1575.     }
  1576.     else if (vdata->view_line_count>vdata->view_lines_per_screen) {
  1577.         vdata->view_scroll=1;
  1578.         setnullpointer(vdata->view_window);
  1579.     }
  1580. }
  1581.  
  1582. void view_setupscreen(vdata)
  1583. struct ViewData *vdata;
  1584. {
  1585.     int a;
  1586.  
  1587.     SetAPen(vdata->view_rastport,vdata->view_colour_table[PEN_TEXTBACKGROUND]);
  1588.     RectFill(vdata->view_rastport,
  1589.         vdata->view_display_left,
  1590.         vdata->view_display_top,
  1591.         vdata->view_display_right,
  1592.         vdata->view_display_bottom);
  1593.  
  1594.     Do3DBox(vdata->view_rastport,
  1595.         2,
  1596.         vdata->view_status_bar_ypos,
  1597.         vdata->view_window->Width-((vdata->view_font->tf_XSize*18)+4),
  1598.         vdata->view_font->tf_YSize,
  1599.         vdata->view_colour_table[PEN_SHINE],
  1600.         vdata->view_colour_table[PEN_SHADOW]);
  1601.  
  1602.     view_status_text(vdata,NULL);
  1603.     SetDrMd(vdata->view_rastport,JAM2);
  1604.  
  1605.     for (a=0;a<9;a++) {
  1606.         vdata->view_gadgets[a].NextGadget=&vdata->view_gadgets[a+1];
  1607.         vdata->view_gadgets[a].LeftEdge=
  1608.             (vdata->view_window->Width-(vdata->view_font->tf_XSize*18))+
  1609.             (a*vdata->view_font->tf_XSize*2);
  1610.         vdata->view_gadgets[a].TopEdge=vdata->view_window->Height-(vdata->view_font->tf_YSize+2);
  1611.         vdata->view_gadgets[a].Width=vdata->view_font->tf_XSize*2;
  1612.         vdata->view_gadgets[a].Height=vdata->view_font->tf_YSize+2;
  1613.         vdata->view_gadgets[a].Flags=GFLG_GADGHCOMP;
  1614.         vdata->view_gadgets[a].Activation=(a<2)?GACT_IMMEDIATE|GACT_RELVERIFY:GACT_RELVERIFY;
  1615.         vdata->view_gadgets[a].GadgetType=GTYP_BOOLGADGET;
  1616.         vdata->view_gadgets[a].GadgetID=a;
  1617.  
  1618.         Do3DBox(vdata->view_rastport,
  1619.             vdata->view_gadgets[a].LeftEdge+2,
  1620.             vdata->view_status_bar_ypos,
  1621.             (vdata->view_font->tf_XSize*2)-4,vdata->view_font->tf_YSize,
  1622.             vdata->view_colour_table[PEN_SHINE],
  1623.             vdata->view_colour_table[PEN_SHADOW]);
  1624.  
  1625.         SetAPen(vdata->view_rastport,vdata->view_colour_table[VIEWPEN_STATUSBACKGROUND]);
  1626.         RectFill(vdata->view_rastport,
  1627.             vdata->view_gadgets[a].LeftEdge+2,
  1628.             vdata->view_status_bar_ypos,
  1629.             vdata->view_gadgets[a].LeftEdge+(vdata->view_gadgets[a].Width-3),
  1630.             vdata->view_window->Height-2);
  1631.         SetAPen(vdata->view_rastport,vdata->view_colour_table[VIEWPEN_STATUSTEXT]);
  1632.         SetBPen(vdata->view_rastport,vdata->view_colour_table[VIEWPEN_STATUSBACKGROUND]);
  1633.  
  1634.         if (a>1) {
  1635.             Move(vdata->view_rastport,
  1636.                 vdata->view_gadgets[a].LeftEdge+
  1637.                     ((vdata->view_gadgets[a].Width-vdata->view_font->tf_XSize)/2),
  1638.                 vdata->view_status_bar_ypos+vdata->view_font->tf_Baseline);
  1639.             Text(vdata->view_rastport,&globstring[STR_VIEW_BUTTONS][a-2],1);
  1640.         }
  1641.     }
  1642.     for (a=0;a<2;a++) {
  1643.         DoArrow(vdata->view_rastport,
  1644.             vdata->view_gadgets[a].LeftEdge+2,
  1645.             vdata->view_window->Height-vdata->view_font->tf_YSize,
  1646.             (vdata->view_font->tf_XSize*2)-4,vdata->view_font->tf_YSize-2,
  1647.             vdata->view_colour_table[VIEWPEN_STATUSTEXT],
  1648.             vdata->view_colour_table[VIEWPEN_STATUSBACKGROUND],a);
  1649.     }
  1650.     SetFont(vdata->view_rastport,vdata->view_font);
  1651. }
  1652.  
  1653. void view_viewhilite(vdata,x,y,x1,y1)
  1654. struct ViewData *vdata;
  1655. int x,y,x1,y1;
  1656. {
  1657.     struct viewhilite *hi;
  1658.  
  1659.     if (!(hi=AllocMem(sizeof(struct viewhilite),MEMF_CLEAR))) return;
  1660.     if (vdata->view_current_hilite) vdata->view_current_hilite->next=hi;
  1661.     else vdata->view_first_hilite=hi;
  1662.     vdata->view_current_hilite=hi;
  1663.     hi->x=x+vdata->view_display_left;
  1664.     hi->y=y+vdata->view_display_top;
  1665.     hi->x1=x1+vdata->view_display_left;
  1666.     hi->y1=y1+vdata->view_display_top;
  1667.     SetDrMd(vdata->view_rastport,COMPLEMENT);
  1668.     RectFill(vdata->view_rastport,hi->x,hi->y,hi->x1,hi->y1);
  1669.     SetDrMd(vdata->view_rastport,JAM1);
  1670. }
  1671.  
  1672. void view_clearhilite(vdata,show)
  1673. struct ViewData *vdata;
  1674. int show;
  1675. {
  1676.     struct viewhilite *hi,*next;
  1677.  
  1678.     hi=vdata->view_first_hilite;
  1679.     if (show) SetDrMd(vdata->view_rastport,COMPLEMENT);
  1680.     while (hi) {
  1681.         next=hi->next;
  1682.         if (show) RectFill(vdata->view_rastport,hi->x,hi->y,hi->x1,hi->y1);
  1683.         FreeMem(hi,sizeof(struct viewhilite));
  1684.         hi=next;
  1685.     }
  1686.     vdata->view_first_hilite=vdata->view_current_hilite=NULL;
  1687.     if (show) SetDrMd(vdata->view_rastport,JAM1);
  1688. }
  1689.  
  1690. void view_fix_scroll_gadget(vdata)
  1691. struct ViewData *vdata;
  1692. {
  1693.     int a,b,c,d;
  1694.  
  1695.     if ((a=GetSliderPos(&vdata->view_gadgets[VIEW_SCROLLGADGET],
  1696.         vdata->view_line_count,
  1697.         vdata->view_lines_per_screen))==vdata->view_text_offset) return;
  1698.  
  1699.     d=vdata->view_text_offset-a;
  1700.     vdata->view_scroll_bar=0;
  1701.  
  1702.     if (d>0 && d<vdata->view_lines_per_screen/2) {
  1703.         while (d--) view_lineup(vdata);
  1704.     }
  1705.     else if (d<0 && d>-(vdata->view_lines_per_screen/2)) {
  1706.         while (d++) view_linedown(vdata);
  1707.     }
  1708.     else if (vdata->view_display_as_hex) {
  1709.         vdata->view_text_offset=a;
  1710.         if (vdata->view_text_offset>vdata->view_last_line)
  1711.             vdata->view_text_offset=vdata->view_last_line;
  1712.         view_displayall(vdata);
  1713.     }
  1714.     else {
  1715.         SetBusyPointer(vdata->view_window);
  1716.         if (a>vdata->view_last_line) a=vdata->view_last_line;
  1717.         if (vdata->view_text_offset<a) {
  1718.             if (a-vdata->view_text_offset<vdata->view_last_line-a) {
  1719.                 for (b=vdata->view_text_offset;b<a;b++) {
  1720.                     for (c=vdata->view_top_buffer_pos;c<vdata->view_file_size;c++) {
  1721.                         if (vdata->view_text_buffer[c]==10)
  1722.                             break;
  1723.                     }
  1724.                     vdata->view_top_buffer_pos=c+1;
  1725.                 }
  1726.             }
  1727.             else {
  1728.                 vdata->view_text_offset=vdata->view_last_line;
  1729.                 vdata->view_top_buffer_pos=vdata->view_file_size;
  1730.                 for (c=0;c<vdata->view_lines_per_screen;c++) {
  1731.                     for (b=vdata->view_top_buffer_pos-2;b>=0;b--) {
  1732.                         if (vdata->view_text_buffer[b]==10)
  1733.                             break;
  1734.                     }
  1735.                     vdata->view_top_buffer_pos=b+1;
  1736.                 }
  1737.                 for (b=a;b<vdata->view_text_offset;b++) {
  1738.                     for (c=vdata->view_top_buffer_pos-2;c>=0;c--) {
  1739.                         if (vdata->view_text_buffer[c]==10)
  1740.                             break;
  1741.                     }
  1742.                     vdata->view_top_buffer_pos=c+1;
  1743.                 }
  1744.             }
  1745.         }
  1746.         else {
  1747.             if (vdata->view_text_offset-a<a) {
  1748.                 for (b=a;b<vdata->view_text_offset;b++) {
  1749.                     for (c=vdata->view_top_buffer_pos-2;c>=0;c--) {
  1750.                         if (vdata->view_text_buffer[c]==10) break;
  1751.                     }
  1752.                     vdata->view_top_buffer_pos=c+1;
  1753.                 }
  1754.             }
  1755.             else {
  1756.                 vdata->view_top_buffer_pos=0;
  1757.                 for (b=0;b<a;b++) {
  1758.                     for (c=vdata->view_top_buffer_pos;c<vdata->view_file_size;c++) {
  1759.                         if (vdata->view_text_buffer[c]==10)
  1760.                             break;
  1761.                     }
  1762.                     vdata->view_top_buffer_pos=c+1;
  1763.                 }
  1764.             }
  1765.         }
  1766.         vdata->view_text_offset=a;
  1767.         view_displayall(vdata);
  1768.         ClearPointer(vdata->view_window);
  1769.     }
  1770.     vdata->view_scroll_bar=1;
  1771. }
  1772.  
  1773. void view_clearsearch(vdata)
  1774. struct ViewData *vdata;
  1775. {
  1776.     vdata->view_search_offset=
  1777.         vdata->view_search_charoffset=
  1778.         vdata->view_pick_offset=
  1779.         vdata->view_pick_charoffset=-1;
  1780. }
  1781.  
  1782. void view_readkeys(req,keys)
  1783. struct IOStdReq *req;
  1784. APTR keys;
  1785. {
  1786.     if (req) {
  1787.         req->io_Length=13;
  1788.         req->io_Data=(APTR)keys;
  1789.         req->io_Command=KBD_READMATRIX;
  1790.         DoIO((struct IORequest *)req);
  1791.     }
  1792. }
  1793.  
  1794. view_simplerequest(struct ViewData *vdata,char *txt,...)
  1795. {
  1796.     char *gads[4],*cancelgad=NULL,*gad;
  1797.     int a=1,r,rets[3],num;
  1798.     va_list ap;
  1799.     struct DOpusSimpleRequest request;
  1800.  
  1801.     va_start(ap,txt); r=1; num=0;
  1802.     for (a=0;a<3;a++) {
  1803.         if (!(gad=(char *)va_arg(ap,char *))) break;
  1804.         if (a==1) cancelgad=gad;
  1805.         else {
  1806.             gads[num]=gad;
  1807.             rets[num++]=r++;
  1808.         }
  1809.     }
  1810.     if (cancelgad) {
  1811.         gads[num]=cancelgad;
  1812.         rets[num]=0;
  1813.         a=num+1;
  1814.     }
  1815.     for (;a<4;a++) gads[a]=NULL;
  1816.  
  1817.     request.hi=vdata->view_colour_table[PEN_SHINE];
  1818.     request.lo=vdata->view_colour_table[PEN_SHADOW];
  1819.     request.fg=vdata->view_colour_table[VIEWPEN_STATUSTEXT];
  1820.     request.bg=vdata->view_colour_table[VIEWPEN_STATUSBACKGROUND];
  1821.  
  1822.     request.strbuf=NULL;
  1823.  
  1824.     return(dorequest(&request,txt,gads,rets,vdata->view_window));
  1825. }
  1826.  
  1827. view_whatsit(vdata,txt,max,buffer)
  1828. struct ViewData *vdata;
  1829. char *txt;
  1830. int max;
  1831. char *buffer;
  1832. {
  1833.     char *gads[3];
  1834.     int rets[2];
  1835.     struct DOpusSimpleRequest request;
  1836.  
  1837.     gads[0]=str_okaystring; rets[0]=1;
  1838.     gads[1]=str_cancelstring; rets[1]=0;
  1839.     gads[2]=NULL;
  1840.  
  1841.     request.hi=vdata->view_colour_table[PEN_SHINE];
  1842.     request.lo=vdata->view_colour_table[PEN_SHADOW];
  1843.     request.fg=vdata->view_colour_table[VIEWPEN_STATUSTEXT];
  1844.     request.bg=vdata->view_colour_table[VIEWPEN_STATUSBACKGROUND];
  1845.  
  1846.     request.strbuf=buffer;
  1847.     request.strlen=max;
  1848.     request.flags=0;
  1849.     return(dorequest(&request,txt,gads,rets,vdata->view_window));
  1850. }
  1851.